<!DOCTYPE html>
  <head>
    <meta charset="utf-8"/>
    <title>Irmin</title>
    <style>
      body {
        font-family: sans-serif;
        background: #222;
        color: #ddd;
        min-width: 600px;
      }

      #list { margin: auto; padding: 5px; }
      #list li {
        list-style-type: none;
        margin: 5px;
        padding: 0px;
        border: 1px solid #ddd;
        color: #ddd;
        display: flex;
        clear: both;
      }

      #list li:hover {
        background: #ddd;
        color: #222;
        cursor: pointer;
      }

      #list li:hover span.item-kind {
        border: 1px solid #222;
      }

      #list li span {
        display: inline-block;
        padding: 10px;
      }

      #list li span.item-path {
        margin-left: 0px;
        line-break: anywhere;
      }

      #list li span.item-hash {
        margin-right: 10px;
        font-family: monospace;
        margin-top: auto;
        margin-bottom: auto;
        margin-left: auto;
        vertical-align: middle;
      }

      #list li span.item-kind {
        padding: 2px;
        border: 1px solid #ddd;
        width: 75px;
        height: 20px;
        vertical-align: middle;
        text-align: center;
        margin-top: auto;
        margin-bottom: auto;
        margin-right: 10px;
      }

      #path, #branch {
        padding: 5px;
        margin: 5px;
        font-size: 110%;
        border: 1px solid #ddd;
        width: 75%;
        background: #222;
        color: #ddd;
      }

      #contents {
        padding: 5px;
        margin: 5px;
        font-family: monospace;
        font-size: 130%;
      }

      h1, h2 {
        padding: 5px;
        margin: 5px;
      }

      #up, #home, #refresh {
        display: inline-block;
        width: 25px;
        height: 25px;
        padding: 7px;
        margin-top: 6px;
        color: white;
        vertical-align: top;
        text-align: center;
        text-decoration: none;
      }


      #up:hover, #home:hover, #refresh:hover {
        cursor: pointer;
        color: #222;
        background: #ddd;
      }

    .no-select {
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }

    .text-select {
      -webkit-user-select: text;
      -moz-user-select: text;
      -ms-user-select: text;
      user-select: text;
    }

    .content-hash {
      font-size: 100%;
      border: 1px solid #ddd;
      padding: 10px;
      margin-bottom: 20px;
      display: table;
    }

    .branch-area, .path-area {
      font-weight: normal;
    }

    .branch-area img, .path-area img {
      vertical-align: middle;
      width: 30px;
      padding-bottom: 5px;
      filter: invert(100%);
    }
    </style>
  </head>
  <body class="no-select">
    <a href="/" style="float: right">
      <img width="75px" style="margin-right:20px; margin-top:10px;" src="">
    </a>
    <h2 class="branch-area">
      <img src="">
      <input id="branch" value="" />
    </div>
    <h2 class="path-area">
      <img alt="svgImg" src=""/>
      <input id="path" value=""/>
      <span class="no-select" id="up">&uarr;</span>
      <span class="no-select" id="refresh">&#8635;</span>
    </h2>
    <ul id="list" class="text-select"></ul>
    <div id="contents" class="text-select"></div>
    <script>
      let list = document.getElementById("list");
      let pathInput = document.getElementById("path");
      let branchInput = document.getElementById("branch");
      function makeElem(data){
        var elem = document.createElement("li");
        var path = document.createElement("span");
        var hash = document.createElement("span");
        var kind = document.createElement("span");

        path.classList.add("item-path");
        path.innerHTML = data.path;

        kind.classList.add("item-kind");
        kind.innerHTML = data.kind;

        hash.classList.add("item-hash");
        hash.innerHTML = data.hash;

        elem.appendChild(path);
        elem.appendChild(hash);
        elem.appendChild(kind);

        elem.onclick = function(){
          update(this.firstChild.innerHTML, branchInput.value);
        }
        return elem;
      }


      function hexdump(buffer, blockSize) {
          blockSize = blockSize || 16;
          var lines = [];
          var hex = "0123456789ABCDEF";
          for (var b = 0; b < buffer.length; b += blockSize) {
              var block = buffer.slice(b, Math.min(b + blockSize, buffer.length));
              var addr = ("0000" + b.toString(16)).slice(-4);
              var codes = block.split('').map(function (ch) {
                  var code = ch.charCodeAt(0);
                  return " " + hex[(0xF0 & code) >> 4] + hex[0x0F & code];
              }).join("");
              codes += "&nbsp;&nbsp;&nbsp;".repeat(blockSize - block.length);
              var chars = block.replace(/[\x00-\x1F\x20]/g, '.');
              chars +=  " ".repeat(blockSize - block.length);
              lines.push(addr + " | " + codes + " | " + chars);
          }
          return lines.join("<br>");
      }
 + "</pre>"
      function getContents(data) {
        if (typeof data.contents === "string") return "<pre>" + data.contents + "</pre>";

        if (data.contents.base64){
          let b = atob(data.contents.base64);
          let s = hexdump(b);
          return s;
        }

        return JSON.stringify(data.contents);
      }

      function update(path, branch) {
        let state = history.state || {};
        if (state.path !== path || state.branch !== branch){
          history.pushState({path: path, branch: branch}, '');
        }

        pathInput.value = path;

        fetch(path + "?branch=" + branch, {method: 'POST'})
        .then(r => r.json())
        .then(data => {
          list.innerHTML = "";
          document.getElementById("contents").innerHTML = "";
          if (data.contents){
            let html = "<div class='content-hash'>" + data.hash + "</div>";
            html += getContents(data);
            document.getElementById("contents").innerHTML = html;
            return;
          }
          for(var i = 0; i < data.length; i++){
            list.appendChild(makeElem(data[i]));
          }
        });
      }


      pathInput.onkeydown = function(e){
        if (e.keyCode == 13){
          update(e.target.value, branchInput.value);
        }
      }

      branchInput.onkeydown = function(e){
        if (e.keyCode == 13){
          update(pathInput.value, e.target.value);
        }
      }

      document.getElementById("up").onclick = function() {
        update(pathInput.value.substring(0, pathInput.value.lastIndexOf('/')), branchInput.value);
      }

      document.getElementById("refresh").onclick = function() {
        list.innerHTML = "";
        update(pathInput.value, branchInput.value);
      }

      window.onpopstate = function(event){
        if (event.state !== null){
          update(event.state.path, event.state.branch);
        }
      }

      window.onload = function() {
        let params = new URLSearchParams(window.location.search);
        pathInput.value = window.location.pathname;
        branchInput.value = params.get("branch") || "main";
        update(pathInput.value, branchInput.value);
      }
    </script>
  </body>
</html>
